<?php

namespace App\Api\Controllers;

use App\Models\MiniUser;
use App\Models\RoomCheckIn;
use App\Models\Users;

use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends BaseController
{
    private function getApp(): \EasyWeChat\MiniProgram\Application
    {
        $mini_config = config("wechat.mini_program.default");
        $storage_path = storage_path('logs/wechat/');
        if (!file_exists($storage_path)) {
            mkdir($storage_path, 0775, true);
            chmod($storage_path, 0775);
        }
        $config = [
            'app_id' => $mini_config['app_id'],
            'secret' => $mini_config['secret'],
            // 下面为可选项
            // 指定 API 调用返回结果的类型：array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',

            'log' => [
                'level' => 'debug',
                'file' => $storage_path . '/' . date("Ymd") . '_wechat.log',
            ],
        ];
        return Factory::miniProgram($config);
    }

    public function login(Request $request)
    {

//        $app = $this->getApp();
//        $code = $request->get("code");
//
//        try {
//            $info = $app->auth->session($code);
//        } catch (InvalidConfigException $e) {
//
//        };

        $info['openid'] = "o1mp25I5dapcFYksdYmFIH8j_3Uc";
        if (!isset($info['openid'])) {
            return Failed("WechatLoginError", ["File" => __CLASS__, "Action" => __FUNCTION__, "Line" => __LINE__]);
        }
        $name = 'wechat_user';
        $nickname = '微信用户';
        $name_py_f = getFullPinYin($nickname);
        $name_py_s = getShortpinyin($nickname);
        $openid = $info['openid'];
        $phone = '13810001000'; // 默认用户手机号 获取手机号时会更新

        $data = [
            'name' => $name,
            'openid' => $openid,
            'nickname' => $nickname,
            'name_py_f' => $name_py_f,
            'name_py_s' => $name_py_s,
            'email' => '',
            'phone' => $phone,
            'avator' => '',
            'status' => 1,
            'updated_at' => date("Y-m-d H:i:s"),
            'created_at' => date("Y-m-d H:i:s"),
        ];

        $mini_user = MiniUser::where([['openid', $openid]])->first();
        if (!$mini_user) {
            $mini_user = MiniUser::create($data);
        }


        if (empty($mini_user) || !$token = JWTAuth::customClaims($info)->fromUser($mini_user)) {
            return Failed(40001, ["File" => __CLASS__, "Action" => __FUNCTION__, "Line" => __LINE__]);
        }
        JWTAuth::setToken($token);

//        dd(JWTAuth::customClaims( $info)->fromUser($mini_user),JWTAuth::toUser());

        // dd($token);

        return $this->respondWithToken(200, $token,$openid);
    }

    public function me(Request $request): \Illuminate\Http\JsonResponse
    {
        try {
//            $room_info = MiniUser::with('roomCheckInfo')->where("openid", $this->user->openid)->first();
            $room_info = (new RoomCheckIn())->getDetail($this->user->openid);
            $data = [
                'user_info' => $this->user,
                'room_info' => $room_info ?? []
            ];
//            $data = [
//            "user_info" => $this->user,
//            "user_role" => $this->getUserRoles(),
//            "user_permissions" => array_values($this->getUserPermissionAndMenu()['permission']),
//            "user_menus" => $this->getUserPermissionAndMenu()['menu']
//            ];
            return $this->success(200, '获取信息成功', $data);
        } catch (\Exception $exception) {
            dd($exception->getMessage());
        } catch (\Throwable $exception) {
            dd($exception->getMessage());
        }

    }

    public function logout(): \Illuminate\Http\JsonResponse
    {

        Auth::guard('api')->logout();

        return Success(20001, ["File" => __CLASS__, "Line" => __FILE__]);
    }


    public function refresh(): \Illuminate\Http\JsonResponse
    {
        $old_token = JWTAuth::getToken()->get();

        $user = JWTAuth::user();
        JWTAuth::invalidate();

        $user = Users::where('name', $user->name)
            ->first();

        if (empty($user) || !$new_token = JWTAuth::fromUser($user)) {
            return Failed(40001, ["File" => "AuthController", "Line" => 64]);
        }

        return $this->success(40006, [
            'access_token' => $new_token,
            'old_access_token' => $old_token,
            'token_type' => 'Bearer',
            'expires_in' => auth('mini_app')->factory()->getTTL() * 60
        ]);

    }
    public function getUserPhone(Request $request)
    {
        $code = $request->get("code");
        $openid = $request->get('openid');
        $app = $this->getApp();
        $accessToken = $app->access_token;
        $token =  $accessToken->getToken();
        $response = $app->httpPostJson('wxa/business/getuserphonenumber?access_token='.$token['access_token'],[
            'code' => $code
        ]);
        if($response['errcode']!=0 || $response['errmsg']!="ok"){
            return $this->fail($response['errcode'],$response['errmsg'],[]);
        }
        $login_ip = $request->getClientIp();
        $login_at = date("Y_m-d H:i:s");
        $mini_user = MiniUser::where("openid",$openid)->first();
        $mini_user->access_token = $token['access_token'];
        $mini_user->phone = $response['phone_info']['phoneNumber'];
        $mini_user->last_login_at = $login_at;
        $mini_user->last_login_ip = $login_ip;
        $mini_user->updated_at = date("Y-m-d H:i:s");
        $mini_user->save();
        $rooms = RoomCheckIn::where("user_phone",$mini_user->phone)->first();
        if($rooms){
            $rooms->openid = $openid;
            $rooms->status = 1;
            $rooms->updated_at = date("Y-m-d H:i:s");
            $rooms->save();
        }
        return $this->success(200,'手机号获取成功',["user_info"=>$mini_user,"room_info"=>$rooms]);
    }

    protected function respondWithToken($code, $token,$openid): \Illuminate\Http\JsonResponse
    {
        return $this->success($code, '', [
            'access_token' => $token,
            'token_type' => 'Bearer',
            'openid' => $openid,
            'expires_in' => auth('mini_app')->factory()->getTTL() * 60
        ]);
    }
}
